package com.xinchao.service.impl;

import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.google.common.collect.Lists;
import com.xinchao.cache.RedisCacheDao;
import com.xinchao.constant.*;
import com.xinchao.dao.UserMapper;
import com.xinchao.exception.ServiceException;
import com.xinchao.model.OperationLog;
import com.xinchao.model.User;
import com.xinchao.model.dto.UserListDTO;
import com.xinchao.model.page.PageInfo;
import com.xinchao.model.vo.UserListVO;
import com.xinchao.model.vo.UserRoleSelectListVO;
import com.xinchao.service.OperationLogService;
import com.xinchao.service.UserService;
import com.xinchao.util.HttpUtils;
import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.servlet.http.HttpServletRequest;
import java.util.List;

/**
 * 用户Service实现类
 *
 * @author dxy
 * @date 2018/6/21 15:27
 */
@Service(value = "userService")
public class UserServiceImpl implements UserService {
    @Autowired
    private UserMapper userMapper;
    @Autowired
    private RedisCacheDao redisCacheDao;
    @Autowired
    private OperationLogService operationLogService;
    private final String user = "user";

    /**
     * 保存用户
     *
     * @param user    User
     * @param roleIds 角色IDS
     * @param request HttpServletRequest
     */
    @Override
    @Transactional(readOnly = false, rollbackFor = Exception.class)
    public void insertUser(User user, String roleIds, HttpServletRequest request) throws ServiceException {
        User loginUser = (User) request.getSession().getAttribute(RequestConstant.SESSION_KEY_USER);
        //MD5加密密码
        String password = user.getPassword();
        if (StringUtils.isBlank(password)) {
            throw new ServiceException("密码不能为空");
        }
        String md5Password = DigestUtils.md5Hex(password);
        user.setSuperAdminUser(BusinessConstant.SUPER_ADMIN_USER_NO);
        user.setPassword(md5Password);
        user.setAddTime(System.currentTimeMillis());
        user.setStatus(BusinessConstant.STATUS_ENABLE);
        //保存用户
        userMapper.insertUser(user);
        Long userId = user.getUserId();
        if (userId == null) {
            throw new ServiceException("保存用户失败");
        }
        //保存用户角色关系
        if (StringUtils.isNotBlank(roleIds)) {
            userMapper.insertUserRole(userId, roleIds.split(","));
        }
        //记录操作日志
        OperationLog operationLog = new OperationLog();
        operationLog.setOperationContent("保存用戶,用戶名为: " + user.getUserName());
        operationLog.setOperationStatus(BusinessConstant.OPERATION_LONG_OPERATION_STATUS_SUCCESS);
        operationLog.setOperationTime(System.currentTimeMillis());
        operationLog.setOperationModule(ModuleConstant.MODULE_USER_PERMISSION + "-" + ModuleConstant.MODULE_USER);
        operationLog.setRealname(loginUser.getRealname());
        operationLog.setUserName(loginUser.getUserName());
        operationLog.setOperationIp(HttpUtils.getRemortIP(request));
        operationLogService.saveOperationLog(operationLog);

        // update by hf at 2018-08-27 用户表有更新，让缓存中的系统用户联系数据失效，此处不重写缓存数据，是为了解耦合。
        expireCacheUserContact();
    }

    private void expireCacheUserContact() {
        redisCacheDao.deleteAll(CacheConstant.CACHE_NAME_ADMIN_USER_CONTACT);
    }

    /**
     * 修改用户
     *
     * @param user    User
     * @param roleIds 角色IDS
     * @param request HttpServletRequest
     */
    @Override
    //此处含义为更新user时，需要更新三个缓存对象
//    @Caching(
//            evict = {
//                    @CacheEvict(key = "'userId:'+#user.userId", value = "user"),
//                    @CacheEvict(key = "'userName:'+#user.userName", value = "user"),
//                    @CacheEvict(key="'realName:'+#user.realname",value = "user")
//            })
    @Transactional(readOnly = false, rollbackFor = Exception.class)
    public void updateUser(User user, String roleIds, HttpServletRequest request) {
        //MD5加密密码
        String password = user.getPassword();
        if (StringUtils.isNotBlank(password)) {
            String md5Password = DigestUtils.md5Hex(password);
            user.setPassword(md5Password);
        }
        user.setUpdateTime(System.currentTimeMillis());
        //更新用户
        userMapper.updateUserById(user);

        Long userId = user.getUserId();
        if (StringUtils.isNotBlank(roleIds)) {
            //删除用户角色关系
            userMapper.deleteUserRoleByUserId(userId);
            //保存用户角色关系
            userMapper.insertUserRole(userId, roleIds.split(","));
        }
        //记录操作日志
        User loginUser = (User) request.getSession().getAttribute(RequestConstant.SESSION_KEY_USER);
        OperationLog operationLog = new OperationLog();
        operationLog.setOperationContent("修改用戶,用戶名为:" + user.getUserName());
        operationLog.setOperationStatus(BusinessConstant.OPERATION_LONG_OPERATION_STATUS_SUCCESS);
        operationLog.setOperationTime(System.currentTimeMillis());
        operationLog.setOperationModule(ModuleConstant.MODULE_USER_PERMISSION + "-" + ModuleConstant.MODULE_USER);
        operationLog.setRealname(loginUser.getRealname());
        operationLog.setUserName(loginUser.getUserName());
        operationLog.setOperationIp(HttpUtils.getRemortIP(request));
        operationLogService.saveOperationLog(operationLog);

        // update by hf at 2018-08-27 用户表有更新，让缓存中的系统用户联系数据失效，此处不重写缓存数据，是为了解耦合。
        expireCacheUserContact();
    }

    /**
     * 通过用户名获取用户
     *
     * @param userName 用户名
     * @return User(用户)
     */
    @Override
    @Transactional(readOnly = true, rollbackFor = Exception.class)
//    @Cacheable(value = "user", key = "'userName:'+#userName")
    public User getUserByUserName(String userName) {
        return userMapper.getUserByUserName(userName);
    }

    /**
     * 获取用戶列表
     *
     * @param status       状态
     * @param userName     用户名
     * @param departmentId 部门ID
     * @param pageNum      当前页
     * @param pageSize     条数
     * @return PageInfo<UserListVO>
     */
    @Override
    @Transactional(readOnly = true, rollbackFor = Exception.class)
    public PageInfo<UserListVO> listUser(Integer status, String userName, Long departmentId, Integer pageNum, Integer pageSize) {
        //设置默认值
        if (pageNum == null) {
            pageNum = PageConstant.DEFAULT_PAGE_NUM;
        }
        if (pageSize == null) {
            pageSize = PageConstant.DEFAULT_PAGE_SIZE;
        }
        PageHelper.startPage(pageNum, pageSize);
        Page<UserListDTO> page = userMapper.listUser(status, userName, departmentId);
        //把Page转化为PageInfo
        PageInfo<UserListVO> pageInfo = new PageInfo<>();
        pageInfo.setPageNum(pageNum);
        pageInfo.setPageSize(pageSize);
        pageInfo.setTotal(page.getTotal());
        List<UserListVO> voList = Lists.newArrayList();
        StringBuilder roleNameSb = new StringBuilder();
        StringBuilder roleIdSb = new StringBuilder();
        for (UserListDTO dto : page.getResult()) {
            UserListVO vo = new UserListVO();
            Long userId = dto.getUserId();
            vo.setUserId(userId);
            vo.setDepartmentId(dto.getDepartmentId());
            vo.setDepartmentName(dto.getDepartmentName());
            vo.setUserName(dto.getUserName());
            vo.setRealname(dto.getRealname());
            vo.setMobilePhone(dto.getMobilePhone());
            vo.setEmail(dto.getEmail());
            vo.setStatus(dto.getStatus());
            vo.setSuperAdminUser(dto.getSuperAdminUser());
            //所属角色
            List<UserRoleSelectListVO> userRoleList = userMapper.listUserRoleName(userId);
            if (CollectionUtils.isNotEmpty(userRoleList)) {
                for (int i = 0; i < userRoleList.size(); i++) {
                    UserRoleSelectListVO userRoleSelectVO = userRoleList.get(i);
                    if (i > 0) {
                        roleNameSb.append(",");
                    }
                    roleNameSb.append(userRoleSelectVO.getRoleName());
                    if (i > 0) {
                        roleIdSb.append(",");
                    }
                    roleIdSb.append(userRoleSelectVO.getRoleId());
                }
                vo.setBelongRole(roleNameSb.toString());
                vo.setBelongRoleIds(roleIdSb.toString());
                roleNameSb.setLength(0);
                roleIdSb.setLength(0);
            } else {
                vo.setBelongRole("");
                vo.setBelongRoleIds("");
            }
            voList.add(vo);
        }
        pageInfo.setList(voList);
        return pageInfo;
    }

    @Override
    @Transactional(readOnly = true, rollbackFor = Exception.class)
//    @Cacheable(value = "user", key = "'userId:'+#userId")
    public User getUserById(Long userId) {
        return userMapper.getUserById(userId);
    }

    /**
     * 根据主键更新
     *
     * @param user
     */
    @Override
    //此处含义为更新user时，需要更新三个缓存对象
//    @Caching(
//            put = {
//                    @CachePut(key = "'userId'+#user.userId", value = "user"),
//                    @CachePut(key = "'userName:'+#user.userName", value = "user"),
//                    @CachePut(key="'realName:'+#user.realname",value = "user")
//                    })
    public void updateByPrimaryKey(User user) {
        userMapper.updateUserById(user);
    }

    /**
     * 通过姓名获取用户
     *
     * @param realName 姓名
     * @return User
     * @throws ServiceException
     */
    @Override
//    @Cacheable(value = "user", key = "'realName:'+#realName")
    public User getUserByRealName(String realName) throws ServiceException {
        if (StringUtils.isBlank(realName)) {
            throw new ServiceException("姓名不能为空");
        }
        return userMapper.getUserByRealName(realName);
    }

    /**
     * 修改密码
     *
     * @param userId   用户ID
     * @param password 密码
     * @throws ServiceException
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public void updatePassword(Long userId, String password, HttpServletRequest request) throws ServiceException {
        if (userId == null || StringUtils.isBlank(password)) {
            throw new ServiceException("输入参数不能为空");
        }
        userMapper.updatePassword(userId, DigestUtils.md5Hex(password));
        //查询用户
        User user = userMapper.getUserById(userId);
        //记录操作日志
        User loginUser = (User) request.getSession().getAttribute(RequestConstant.SESSION_KEY_USER);
        OperationLog operationLog = new OperationLog();
        operationLog.setOperationContent("修改登录密码");
        operationLog.setOperationStatus(BusinessConstant.OPERATION_LONG_OPERATION_STATUS_SUCCESS);
        operationLog.setOperationTime(System.currentTimeMillis());
        operationLog.setOperationModule(ModuleConstant.MODULE_SYSTEM + "-" + ModuleConstant.MODULE_SYSTEM_UPDATE_PASSWORD);
        operationLog.setRealname(loginUser.getRealname());
        operationLog.setUserName(loginUser.getUserName());
        operationLog.setOperationIp(HttpUtils.getRemortIP(request));
        operationLogService.saveOperationLog(operationLog);
    }

    /**
     * 重置密码
     *
     * @param userId   用户ID
     * @param password 密码
     * @param request  HttpServletRequest
     * @throws ServiceException
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public void resetPassword(Long userId, String password, HttpServletRequest request) throws ServiceException {
        if (userId == null || StringUtils.isBlank(password) || request == null) {
            throw new ServiceException("输入参数不能为空");
        }
        //查询用户
        User user = userMapper.getUserById(userId);
        if (user == null) {
            throw new ServiceException("用户不存在，请联系管理员");
        }
        userMapper.updatePassword(userId, DigestUtils.md5Hex(password));
        //记录操作日志
        User loginUser = (User) request.getSession().getAttribute(RequestConstant.SESSION_KEY_USER);
        OperationLog operationLog = new OperationLog();
        operationLog.setOperationContent("重置用户" + user.getUserName() + "的登录密码");
        operationLog.setOperationStatus(BusinessConstant.OPERATION_LONG_OPERATION_STATUS_SUCCESS);
        operationLog.setOperationTime(System.currentTimeMillis());
        operationLog.setOperationModule(ModuleConstant.MODULE_SYSTEM + "-" + ModuleConstant.MODULE_SYSTEM_UPDATE_PASSWORD);
        operationLog.setRealname(loginUser.getRealname());
        operationLog.setUserName(loginUser.getUserName());
        operationLog.setOperationIp(HttpUtils.getRemortIP(request));
        operationLogService.saveOperationLog(operationLog);
    }

    /**
     * 启用禁用用户
     *
     * @param userId  用户ID
     * @param status  状态
     * @param request HttpServletRequest
     * @throws ServiceException
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public void enableDisableUser(Long userId, Integer status, HttpServletRequest request) throws ServiceException {
        if (userId == null || status == null || request == null) {
            throw new ServiceException("输入参数不能为空");
        }
        User user = userMapper.getUserById(userId);
        if (user == null) {
            throw new ServiceException("用户不存在，请联系管理员");
        }
        userMapper.enableDisableUser(userId, status);
        //记录操作日志
        User loginUser = (User) request.getSession().getAttribute(RequestConstant.SESSION_KEY_USER);
        OperationLog operationLog = new OperationLog();
        if (BusinessConstant.STATUS_ENABLE == status) {
            operationLog.setOperationContent("修改用戶,启用用戶" + user.getUserName());
        } else {
            operationLog.setOperationContent("修改用戶,禁用用户" + user.getUserName());
        }
        operationLog.setOperationStatus(BusinessConstant.OPERATION_LONG_OPERATION_STATUS_SUCCESS);
        operationLog.setOperationTime(System.currentTimeMillis());
        operationLog.setOperationModule(ModuleConstant.MODULE_USER_PERMISSION + "-" + ModuleConstant.MODULE_USER);
        operationLog.setRealname(loginUser.getRealname());
        operationLog.setUserName(loginUser.getUserName());
        operationLog.setOperationIp(HttpUtils.getRemortIP(request));
        operationLogService.saveOperationLog(operationLog);

    }

    /**
     * 批量启用禁用用户
     * @param ids 用户id（多个英文逗号隔开）
     * @param status 状态
     * @param loginUser 登录用户
     * @param ip 登录用户的ip
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public void batchAbleDisable(String ids, Integer status, User loginUser, String ip) throws ServiceException {
        StringBuilder userNames = new StringBuilder();
        if(StringUtils.isNotBlank(ids)){
            String[] idArr = ids.split(",");
            if(idArr.length > 0){
                for (String id : idArr) {
                    User user = userMapper.getUserById(Long.parseLong(id));
                    if(user == null){
                        throw new ServiceException("用户不存在，请联系管理员");
                    }
                    userNames.append(",").append(user.getUserName());
                    userMapper.enableDisableUser(Long.parseLong(id), status);
                }
            }
            if(StringUtils.isNotBlank(userNames)){
                String content = "";
                if (BusinessConstant.STATUS_ENABLE == status) {
                    content = "批量启用用户，启用用户为：" + userNames.toString().substring(1);
                } else {
                    content = "批量禁用用户，禁用用户为：" + userNames.toString().substring(1);
                }
                operationLogService.saveSuccessOperationLog(content,
                        (ModuleConstant.MODULE_USER_PERMISSION + "-" + ModuleConstant.MODULE_USER), loginUser, ip);
            }
        }
    }
}
